﻿#region Using directives

using System;
using System.Xml;
using System.Text;
using System.DirectoryServices;
using MCMLXVII.BackEnd.Data.SystemDatabase;

#endregion

namespace MCMLXVII.SubSystems.Security.DirectoryServices
{
    public class NTDomain: IDirectoryService
    {
        public NTDomain()
        {

        }

        #region IDirectoryService Members

        bool IDirectoryService.LogonUser(string FQDN, string NetBiosName, string  DirConfigInfo, string UserName, string Password)
        {

            try
            {
                DirectoryEntry mDirEntry = new DirectoryEntry("WinNT://" + NetBiosName, UserName, Password,AuthenticationTypes.Secure);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public XmlDocument GetDirectoryUsersList(string path, XmlDocument DirConfigInfo, string NameFilter)
        {
            string UserName = "";
            string Password = "";
            if (DirConfigInfo.SelectSingleNode("Info/UserName") != null)
                UserName = DirConfigInfo.SelectSingleNode("Info/UserName").InnerText;
            if (DirConfigInfo.SelectSingleNode("Info/Password") != null)
                Password = DirConfigInfo.SelectSingleNode("Info/Password").InnerText;

            StringBuilder sb = new StringBuilder();
            sb.Append("<Root Path=\"" + path + "\">");

            DirectoryEntry DirEntry;
            if (UserName != "")
                DirEntry = new DirectoryEntry(path, UserName, Password);
            else
                DirEntry = new DirectoryEntry(path, UserName, Password);
            try
            {
                foreach (DirectoryEntry de in DirEntry.Children)
                {
                    if (de.SchemaClassName.ToLower() == "user")
                    {
                        sb.Append("<Node Name=\"" + de.Name  + "\" Path=\"" + de.Path  + "\" ID=\"" + de.Guid + "\" LogonName=\"" + de.Name + "\" >");
                        //Append property Maps
                        foreach (XmlNode node in DirConfigInfo.SelectSingleNode("Info/AditionalMappings"))
                        {
                            try
                            {
                                sb.Append("<Property Name=\"" + node.Attributes.GetNamedItem("destination").Value + "\" Value=\"");
                                switch(node.Attributes.GetNamedItem("source").Value.ToLower())
                                {
                                    case "name": sb.Append(de.Name);
                                        break;
                                    case "guid": sb.Append(de.Guid);
                                        break;
                                    case "username": sb.Append(de.Username);
                                        break;
                                    case "path": sb.Append(de.Path);
                                        break;
                                    default:
                                        foreach (System.DirectoryServices.PropertyValueCollection p in de.Properties.Values)
                                        {  
                                            if (p.PropertyName.ToLower() ==  node.Attributes.GetNamedItem("source").Value.ToLower())
                                                sb.Append(p.Value);
                                        }
                                        break;
                                }
                                sb.Append("\" />");
                            }
                            catch
                            {
                                // nothing to do, the property is not accesible or not applicable to the object class
                            }
                        }

                        sb.Append("</Node>");
                    }
                }
            }
            catch // (Exception ex)
            {
                //nothing to do
            }

            sb.Append("</Root>");
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(sb.ToString());
            return xDoc;
        }

        public XmlDocument GetDirectoryGroupsList(string Path, XmlDocument DirConfigInfo, string NameFilter)
        {
            string UserName = "";
            string Password = "";
            if (DirConfigInfo.SelectSingleNode("Info/UserName") != null)
                UserName = DirConfigInfo.SelectSingleNode("Info/UserName").InnerText;
            if (DirConfigInfo.SelectSingleNode("Info/Password") != null)
                Password = DirConfigInfo.SelectSingleNode("Info/Password").InnerText;

            StringBuilder sb = new StringBuilder();
            sb.Append("<Root Path=\"" + Path + "\">");

            DirectoryEntry DirEntry;
            if (UserName != "")
                DirEntry = new DirectoryEntry(Path, UserName, Password);
            else
                DirEntry = new DirectoryEntry(Path, UserName, Password);
            try
            {
                foreach (DirectoryEntry de in DirEntry.Children)
                {
                    if (de.SchemaClassName.ToLower() == "group")
                    {
                        sb.Append("<Node Name=\"" + de.Name + "\" Path=\"" + de.Path + "\" ID=\"" + de.Guid + "\" LogonName=\"" + de.Name + "\" >");
                        //Append property Maps
                        foreach (XmlNode node in DirConfigInfo.SelectSingleNode("Info/AditionalMappings"))
                        {
                            try
                            {
                                sb.Append("<Property Name=\"" + node.Attributes.GetNamedItem("destination").Value + "\" Value=\"");
                                switch (node.Attributes.GetNamedItem("source").Value.ToLower())
                                {
                                    case "name": sb.Append(de.Name);
                                        break;
                                    case "guid": sb.Append(de.Guid);
                                        break;
                                    case "username": sb.Append(de.Username);
                                        break;
                                    case "path": sb.Append(de.Path);
                                        break;
                                    default:
                                        foreach (System.DirectoryServices.PropertyValueCollection p in de.Properties.Values)
                                        {
                                            if (p.PropertyName.ToLower() == node.Attributes.GetNamedItem("source").Value.ToLower())
                                                sb.Append(p.Value);
                                        }
                                        break;
                                }
                                sb.Append("\" />");
                            }
                            catch
                            {
                                // nothing to do, the property is not accesible or not applicable to the object class
                            }
                        }
                        sb.Append("</Node>");
                    }
                }
            }
            catch // (Exception ex)
            {
                //nothing to do
            }
            sb.Append("</Root>");
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(sb.ToString());
            return xDoc;
        }

        public string GetRoot(string FQDN, string NetbiosName)
        {
            return "WinNT://" + NetbiosName;
        }
        #endregion
    }
}
